package br.mg.bhe.ftpobre.command;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.SocketException;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;

import br.mg.bhe.ftpobre.ConnectionData;
import br.mg.bhe.ftpobre.Main;
import br.mg.bhe.ftpobre.log.FtpLogView;
import br.mg.bhe.ftpobre.util.LogUtil;

/**
 *
 * @author Aureliano
 */
public class ConnectionCommand implements ICommand {

	private static final Logger logger = LogUtil.getLogger(ConnectionCommand.class);
	
    public void execute() {
        if (this.canExecute()) {
            this.doAction();
        }
    }

    public boolean canExecute() {
        return !Main.getConnectionData().isConnected();
    }

    private void doAction() {
        ConnectionData c = Main.getConnectionData();
        FTPSClient ftpClient = new FTPSClient("SSL");
        ftpClient.addProtocolCommandListener(this.createPrintCommandListener());

        try {
        	FtpLogView.log("Abrindo conexão com " + c.getHost() + " na porta " + c.getPort());
            ftpClient.connect(c.getHost(), c.getPort());

            if (FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
            	FtpLogView.log("Conexão aberta com " + c.getHost() + " na porta " + c.getPort());
                ftpClient.login(c.getUser(), c.getPassword());
                ftpClient.enterLocalPassiveMode();
                FtpLogView.log("Autenticação realizada para usuário " + c.getUser());
            } else {
            	FtpLogView.log("Conexão recusada para o host " + c.getHost());
            	FtpLogView.log("Desconectando...");
                ftpClient.disconnect();
            }
            c.setFtpClient(ftpClient);
            c.setWorkingOnline(true);
        } catch (SocketException ex) {
        	FtpLogView.log(ex.getMessage());
        	logger.log(Level.SEVERE, ex.getMessage(), ex);
        	throw new RuntimeException(ex);
        } catch (IOException ex) {
        	FtpLogView.log(ex.getMessage());
        	logger.log(Level.SEVERE, ex.getMessage(), ex);
        	throw new RuntimeException(ex);
        }
    }
    
    private PrintCommandListener createPrintCommandListener() {
    	try {
			return new PrintCommandListener(
					new PrintWriter(this.getCommandListenerOutputFile()));
		} catch (FileNotFoundException ex) {
			logger.log(Level.SEVERE, ex.getMessage(), ex);
			throw new RuntimeException(ex);
		}
    }
    
    private String getCommandListenerOutputFile() {
    	return new File("").getAbsolutePath() +
    			"/log/protocol_command_listener_output.log";
    }
}
